<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button class="btn">点击我防抖1</button>
    <button class="btn2">点击我防抖2</button>
  </body>
</html>
<script>
  // 1.函数的执行

  // function fn(){
  //     var a = 10;
  //     console.log(a);
  // }
  // fn();
  // console.log(a);
  // 函数 创建  执行 销毁 （垃圾回收机制）

  // var a = 10;
  // function fn(){
  //     console.log(a)
  // }
  // fn();
  // console.log(a);

  // 2.如果一个函数对于外部的环境（context）有引用 那么这个外部环境不会被销毁；（闭包）

  // 一个函数和对其周围状态（lexical environment，词法环境）的引用捆绑在一起
  // （或者说函数被引用包围），这样的组合就是闭包（closure）
  //     function fn(){
  //         var a = 0;
  //         return function(){
  //             a++;
  //             console.log(a);
  //         }
  //     }
  //    var myfn =  fn();
  //    myfn();
  //    myfn();
  //    myfn();

  // 闭包 1.延迟执行  2. 缓存
  // function fn(a){
  //     console.log(a);
  //     return function(b){
  //         console.log(b)
  //         return a + b;
  //     }
  // }
  // // 分步执行
  // var fn1 = fn(1);
  // setTimeout(function(){
  //     var res = fn1(2);
  //     console.log(res);
  // }, 1000);
  // 2.缓存
  // var fn = function(){
  //     console.log("fn");
  // }

  // function once(fn){
  //     var isExe = false;  // 缓存函数的执行结果；
  //     return function(){
  //         if(!isExe){
  //             fn();
  //             isExe = true;
  //         }else{
  //             console.log("这个函数已经被执行了");
  //         }
  //     }
  // }
  // var myfn = once(fn);
  // myfn();  // 只能执行一次
  // myfn();  // 不能在执行了
  // myfn();  // 不能在执行了
  // myfn = null;
  // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

  // 通用防抖
  var btnEle = document.querySelector(".btn");
  var btnEle2 = document.querySelector(".btn2");
  var fn = function () {
    console.log(1111);
  };
  btnEle.onclick = debounce1(fn, 1000);
  var btnEle2 = document.querySelector(".btn2");
  btnEle2.onclick = debounce2(function () {
    console.log(2222);
  }, 200);

  //   后置防抖

  function debounce1(fn, delay) {
    var timer = null;
    return function () {
      clearTimeout(timer);
      timer = setTimeout(function () {
        fn();
      }, delay);
    };
  }

  //  前置防抖

  function debounce2(fn, delay) {
    var timer = null;
    return function () {
      !timer && fn();
      clearTimeout(timer);
      timer = setTimeout(function () {
        timer = null;
      }, delay);
    };
  }
</script>
